package com.spring.dynamic.jar.core;

import org.springframework.util.ClassUtils;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.jar.JarFile;

/**
 * AddonClassLoader
 *
 * @author Brant Liu <br> 邮箱：<br>lbf1988@qq.com <br>日期：<br>2018/04/09
 * @version 1.0.0
 */
public class AddonClassLoader {
    private final static String   METHOD_ADD_URL        = "addURL";
    private final static Class<?> METHOD_PARAMETER_TYPE = URL.class;
    private File file;

    public AddonClassLoader() {
    }

    public AddonClassLoader(File file) {
        this.file = file;
    }

    public void loadJar() throws MalformedURLException, NoSuchMethodException {
        checkFileNotNull();
        URL jarUrl = this.getFile().toURI().toURL();
        Method method = URLClassLoader.class.getDeclaredMethod(METHOD_ADD_URL, METHOD_PARAMETER_TYPE);
        boolean accessible = method.isAccessible();
        if(false == accessible){
            method.setAccessible(true);
        }
        // TODO: 2018/04/09 获取当前线程的类加载器
        URLClassLoader classLoader = (URLClassLoader) ClassUtils.getDefaultClassLoader();
        try {
            method.invoke(classLoader,jarUrl);
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            method.setAccessible(accessible);
        }
    }

    public JarFile getJarFile() throws IOException {
        checkFileNotNull();
        return new JarFile(file);
    }

    private void checkFileNotNull(){
        if(!getFile().exists()){
            throw new RuntimeException("File must be not null");
        }
    }

    public File getFile() {
        return file;
    }

    public void setFile(File file) {
        this.file = file;
    }
}
